/*
 *  Copyright (c) 2013 Hai Bison
 *
 *  See the file LICENSE at the root directory of this project for copying
 *  permission.
 */

package com.haibison.android.hutieu;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.net.Uri.Builder;
import android.text.TextUtils;

/**
 * Contract for {@link ShareProvider}.
 * 
 * @author Hai Bison
 * 
 */
public class ShareContract {

    /**
     * The authority suffix.
     */
    public static final String AUTHORITY_SUFFIX = Sys.LIB_CODE_NAME;

    /**
     * The content type.
     */
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.haibison.android.lib."
            + Sys.LIB_CODE_NAME;

    /**
     * The content item type.
     */
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.haibison.android.lib."
            + Sys.LIB_CODE_NAME;

    /**
     * The path "id".
     */
    public static final String PATH_ID = "id";

    /**
     * The path "name".
     */
    public static final String PATH_NAME = "name";

    /**
     * The path "asset".
     */
    public static final String PATH_ASSET = "asset";

    /**
     * The path "settings".
     */
    public static final String PATH_SETTINGS = "settings";

    /**
     * Use this parameter to map the resource name back to the resource ID.
     * <p/>
     * Type: Integer.
     * 
     * @see #PATH_NAME
     */
    public static final String PARAM_RES_ID = "res_id";

    /**
     * Use this parameter to map the resource name back to the resource asset
     * path.
     * <p/>
     * Type: String.
     * 
     * @see #PATH_NAME
     */
    public static final String PARAM_RES_ASSET = "res_asset";

    /**
     * Use this parameter to set MIME for the resource.
     * <p/>
     * Type: String.
     */
    public static final String PARAM_MIME = "mime";

    /**
     * Use this parameter to tell the provider that the requested resource is
     * compressed. So the provider will know how to handle it. Default is
     * {@code false}.
     */
    public static final String PARAM_COMPRESSED = "compressed";

    /**
     * The passport used when sending request to internal URIs.
     * 
     * @see ShareProviderUtils#genPassport(Context)
     * @see ShareProviderUtils#validatePassport(Context, String)
     */
    public static final String PARAM_PASSPORT = "passport";

    /**
     * Use this parameter to explicitly use socket instead of other methods.
     * Default is {@code false}.
     */
    public static final String PARAM_USE_SOCKET = "use_socket";

    /**
     * This is singleton class.
     */
    private ShareContract() {
    }// ShareContract()

    /**
     * Gets the authority of this provider.
     * 
     * @param context
     *            the context.
     * @return the authority.
     */
    public static final String getAuthority(Context context) {
        return context.getPackageName() + '.' + AUTHORITY_SUFFIX;
    }// getAuthority()

    /**
     * Generates a content URI base for a single item. Callers must append a
     * resource ID to this URI to retrieve the resource.
     * 
     * @param context
     *            the context.
     * @return the base content ID URI.
     */
    public static final Uri genContentIdUriBase(Context context) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(getAuthority(context)).appendPath(PATH_ID).build();
    }// genContentIdUriBase()

    /**
     * Generates a content URI base for a single item. Callers must append a
     * name to this URI <b>and</b> the resource ID with {@link #PARAM_RES_ID} to
     * retrieve the resource.
     * 
     * @param context
     *            the context.
     * @return the base content ID URI.
     */
    public static final Uri genContentNameUriBase(Context context) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(getAuthority(context)).appendPath(PATH_NAME).build();
    }// genContentNameUriBase()

    /**
     * Generates a content URI base for a single item. Callers must append full
     * path to asset resource to this URI. You can also provide its MIME with
     * {@link #PARAM_MIME}.
     * 
     * @param context
     *            the context.
     * @return the base content ID URI.
     */
    public static final Uri genContentAssetUriBase(Context context) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(getAuthority(context)).appendPath(PATH_ASSET)
                .build();
    }// genContentAssetUriBase()

    /**
     * Generates a content URI base for settings. You can use it to notify
     * changes from client.
     * 
     * @param context
     *            the context.
     * @return the base content URI for settings.
     */
    public static final Uri genContentSettingsUriBase(Context context) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(getAuthority(context)).appendPath(PATH_SETTINGS)
                .build();
    }// genContentSettingsUriBase()

    /**
     * Generates the URI pointing to a resource ID.
     * 
     * @param context
     *            the context.
     * @param resId
     *            the resource ID.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @return the URI which points to a resource ID.
     */
    public static final Uri genContentIdUri(Context context, int resId,
            boolean compressed) {
        return genContentIdUri(context, resId, compressed, null);
    }// genContentIdUri()

    /**
     * Generates the URI pointing to a resource ID.
     * 
     * @param context
     *            the context.
     * @param resId
     *            the resource ID.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @param mime
     *            the MIME type for this resource, can be {@code null}.
     * @return the URI which points to a resource ID.
     */
    public static final Uri genContentIdUri(Context context, int resId,
            boolean compressed, String mime) {
        Builder uriBuilder = genContentIdUriBase(context)
                .buildUpon()
                .appendPath(Integer.toString(resId))
                .appendQueryParameter(PARAM_COMPRESSED,
                        Boolean.toString(compressed));
        if (TextUtils.isEmpty(mime))
            return uriBuilder.build();
        return uriBuilder.appendQueryParameter(PARAM_MIME, mime).build();
    }// genContentIdUri()

    /**
     * Generates the URI pointing to a resource ID.
     * 
     * @param context
     *            the context.
     * @param resId
     *            the resource ID.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @param name
     *            the human readable name of this resource.
     * @return the URI which points to a resource ID.
     * @see #PARAM_RES_ID
     */
    public static final Uri genContentNameUri(Context context, int resId,
            boolean compressed, String name) {
        return genContentNameUri(context, resId, compressed, name, null);
    }// genContentNameUri()

    /**
     * Generates the URI pointing to a resource ID.
     * 
     * @param context
     *            the context.
     * @param resId
     *            the resource ID.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @param name
     *            the human readable name of this resource.
     * @param mime
     *            the MIME type for this resource, can be {@code null}.
     * @return the URI which points to a resource ID.
     * @see #PARAM_RES_ID
     * @see #PARAM_MIME
     */
    public static final Uri genContentNameUri(Context context, int resId,
            boolean compressed, String name, String mime) {
        Builder uriBuilder = genContentNameUriBase(context)
                .buildUpon()
                .appendPath(name)
                .appendQueryParameter(PARAM_RES_ID, Integer.toString(resId))
                .appendQueryParameter(PARAM_COMPRESSED,
                        Boolean.toString(compressed));
        if (TextUtils.isEmpty(mime))
            return uriBuilder.build();
        return uriBuilder.appendQueryParameter(PARAM_MIME, mime).build();
    }// genContentNameUri()

    /**
     * Generates the URI pointing to an asset resource.
     * 
     * @param context
     *            the context.
     * @param assetPath
     *            the path to asset resource.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @param name
     *            the human readable name of this resource.
     * @return the URI which points to an asset resource.
     * @see #PARAM_RES_ID
     * @see #PARAM_MIME
     */
    public static final Uri genContentNameUri(Context context,
            String assetPath, boolean compressed, String name) {
        return genContentNameUri(context, assetPath, compressed, name, null);
    }// genContentNameUri()

    /**
     * Generates the URI pointing to an asset resource.
     * 
     * @param context
     *            the context.
     * @param assetPath
     *            the path to asset resource.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @param name
     *            the human readable name of this resource.
     * @param mime
     *            the MIME type for this resource, can be {@code null}.
     * @return the URI which points to an asset resource.
     * @see #PARAM_RES_ID
     * @see #PARAM_MIME
     */
    public static final Uri genContentNameUri(Context context,
            String assetPath, boolean compressed, String name, String mime) {
        Builder uriBuilder = genContentNameUriBase(context)
                .buildUpon()
                .appendPath(name)
                .appendQueryParameter(PARAM_RES_ASSET, assetPath)
                .appendQueryParameter(PARAM_COMPRESSED,
                        Boolean.toString(compressed));
        if (TextUtils.isEmpty(mime))
            return uriBuilder.build();
        return uriBuilder.appendQueryParameter(PARAM_MIME, mime).build();
    }// genContentNameUri()

    /**
     * Generates the URI pointing to an asset.
     * 
     * @param context
     *            the context.
     * @param pathname
     *            the full path to the asset resource.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @return the URI which points to the asset resource.
     */
    public static final Uri genContentAssetUri(Context context,
            String pathname, boolean compressed) {
        return genContentAssetUri(context, pathname, compressed, null);
    }// genContentAssetUri()

    /**
     * Generates the URI pointing to an asset.
     * 
     * @param context
     *            the context.
     * @param pathname
     *            the full path to the asset resource.
     * @param compressed
     *            specifies whether this resource is compressed or not.
     * @param mime
     *            the MIME type, can be {@code null}.
     * @return the URI which points to the asset resource.
     */
    public static final Uri genContentAssetUri(Context context,
            String pathname, boolean compressed, String mime) {
        Builder uriBuilder = genContentAssetUriBase(context)
                .buildUpon()
                .appendPath(pathname)
                .appendQueryParameter(PARAM_COMPRESSED,
                        Boolean.toString(compressed));
        if (TextUtils.isEmpty(mime))
            return uriBuilder.build();
        return uriBuilder.appendQueryParameter(PARAM_MIME, mime).build();
    }// genContentAssetUri()

}
